package lion.framework.core.patch;

import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import lion.dev.io.Zip;
import lion.framework.core.conf.Config;
import lion.framework.core.conf.ConfigManager;
import lion.framework.core.util.AppPaths;

/**
 * 升级管理器，任何需要重启的升级将无法处理。
 *
 * <pre>
 * time   2013 2013年12月27日 上午11:47:29
 * mail   hl_0074@sina.com
 * </pre>
 *
 * @author lion
 */
public class PatchManager {

	private static Map<Integer, IPatch> updaters = new TreeMap<>();

	private static Log log = LogFactory.getLog(PatchManager.class);

	public static void update() throws Exception {

		if (updaters.isEmpty()) { return; }
		int cv = getCurrentVersion();
		log.info("sytem current version " + cv);
		boolean patched = false;
		try {
			for (Integer version : updaters.keySet()) {
				if (version <= cv) {
					continue;
				}
				if (!patched) {
					backupConfig(cv);
				}
				patched = true;
				log.debug("update to version " + version);
				IPatch patcher = updaters.get(version);

				patcher.patch();
				cv = version;
			}
		} catch (Exception e) {
			log.error("update error ", e);
		} finally {
			if (patched) {
				updatePatchVersion(cv);
			}
		}
		log.info("system update finished ,current version " + cv);
	}

	private static void backupConfig(int version) throws IOException {

		File classPath = new File(URLDecoder.decode(PatchManager.class.getResource("").getPath(), "UTF-8"));

		List<File> files = new ArrayList<>();
		for (File sub : classPath.listFiles()) {
			if (sub.isDirectory()) {
				continue;
			}
			files.add(sub);
		}

		File folder = new File(AppPaths.WEBINF + "/backup/config/");
		if (!folder.exists()) {
			folder.mkdirs();
		}
		Zip.compress(AppPaths.WEBINF + "/backup/config/config_" + version + ".zip", files.toArray(new File[0]));
	}

	private static void updatePatchVersion(int cv) throws Exception {

		Config config = ConfigManager.getConfig("framework");
		config.put("framework.patch", cv);
		config.save();
	}

	public static void addUdpater(int version, IPatch updater) {

		updaters.put(version, updater);
	}

	public static int getCurrentVersion() {

		Config config = ConfigManager.getConfig("framework");
		int version = config.getInt("framework.patch", 1);

		return version;
	}
}
